/**
 * 人脸登录组件
 * 支持实时摄像头进行人脸识别登录
 * 
 * @author 项目开发团队
 * @version 2.0.0
 */

import React, { useState, useRef, useCallback, useEffect } from 'react';
import { Button, Dialog, Toast, Card } from 'antd-mobile';
import { searchFace, detectFace, convertImageToBase64 } from '../../services/faceRecognitionService';
import styles from './index.module.css';

const FaceLogin = ({ 
  visible, 
  onClose, 
  onSuccess, 
  onRegister,
  qualityControl = 'NORMAL',
  livenessControl = 'NORMAL',
  threshold = 80
}) => {
  const [isProcessing, setIsProcessing] = useState(false);
  const [detectResult, setDetectResult] = useState(null);
  const [searchResult, setSearchResult] = useState(null);
  const [cameraError, setCameraError] = useState('');
  const [isDetecting, setIsDetecting] = useState(false);
  const [detectionCount, setDetectionCount] = useState(0);
  const [lastDetectionTime, setLastDetectionTime] = useState(null);
  
  const videoRef = useRef(null);
  const canvasRef = useRef(null);
  const streamRef = useRef(null);
  const detectionIntervalRef = useRef(null);

  // 重置状态
  const resetState = useCallback(() => {
    setIsProcessing(false);
    setDetectResult(null);
    setSearchResult(null);
    setCameraError('');
    setIsDetecting(false);
    setDetectionCount(0);
    setLastDetectionTime(null);
    stopCamera();
  }, []);

  // 关闭弹窗
  const handleClose = useCallback(() => {
    resetState();
    onClose();
  }, [resetState, onClose]);

  // 启动摄像头
  const startCamera = useCallback(async () => {
    try {
      setCameraError('');
      const stream = await navigator.mediaDevices.getUserMedia({
        video: {
          width: { ideal: 640 },
          height: { ideal: 480 },
          facingMode: 'user' // 前置摄像头
        },
        audio: false
      });
      
      streamRef.current = stream;
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        videoRef.current.play();
      }
      
      // 开始自动检测
      startAutoDetection();
      
    } catch (error) {
      console.error('摄像头启动失败:', error);
      let errorMessage = '摄像头启动失败';
      
      if (error.name === 'NotAllowedError') {
        errorMessage = '请允许访问摄像头权限';
      } else if (error.name === 'NotFoundError') {
        errorMessage = '未找到摄像头设备';
      } else if (error.name === 'NotReadableError') {
        errorMessage = '摄像头被其他应用占用';
      }
      
      setCameraError(errorMessage);
      Toast.show(errorMessage);
    }
  }, []);

  // 停止摄像头
  const stopCamera = useCallback(() => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach(track => track.stop());
      streamRef.current = null;
    }
    
    if (detectionIntervalRef.current) {
      clearInterval(detectionIntervalRef.current);
      detectionIntervalRef.current = null;
    }
    
    setIsDetecting(false);
  }, []);

  // 开始自动检测
  const startAutoDetection = useCallback(() => {
    if (detectionIntervalRef.current) return;
    
    setIsDetecting(true);
    detectionIntervalRef.current = setInterval(() => {
      captureAndDetect();
    }, 5000); // 每5秒检测一次，避免API限制
  }, []);

  // 捕获画面并检测
  const captureAndDetect = useCallback(async () => {
    if (!videoRef.current || !canvasRef.current || isProcessing) return;
    
    const video = videoRef.current;
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    
    // 检查视频是否已加载
    if (video.videoWidth === 0 || video.videoHeight === 0) return;
    
    // 设置canvas尺寸
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    
    // 绘制当前帧
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
    
    // 转换为Blob
    const blob = await new Promise(resolve => {
      canvas.toBlob(resolve, 'image/jpeg', 0.8);
    });
    
    // 转换为File对象
    const file = new File([blob], 'camera-capture.jpg', { type: 'image/jpeg' });
    
    // 更新检测计数和时间
    setDetectionCount(prev => prev + 1);
    setLastDetectionTime(new Date());
    
    // 开始人脸识别
    await handleFaceRecognition(file);
  }, [isProcessing]);

  // 手动捕获
  const handleManualCapture = useCallback(async () => {
    if (!videoRef.current || isProcessing) return;
    
    setIsProcessing(true);
    await captureAndDetect();
  }, [captureAndDetect, isProcessing]);

  // 人脸识别
  const handleFaceRecognition = useCallback(async (file) => {
    if (!file || isProcessing) return;

    setIsProcessing(true);
    
    try {
      // 转换图片为Base64
      const base64Image = await convertImageToBase64(file);
      
      // 先进行人脸检测
      const detectResult = await detectFace(base64Image);
      
      if (!detectResult.success) {
        setSearchResult({ found: false, error: detectResult.error });
        return;
      }

      const faceList = detectResult.data.face_list;
      
      if (!faceList || faceList.length === 0) {
        setSearchResult({ found: false, error: '未检测到人脸' });
        return;
      }

      const face = faceList[0];
      setDetectResult(face);
      
      // 检查人脸质量
      const quality = face.quality;
      if (quality) {
        if (quality.occlusion?.left_eye > 0.6 || 
            quality.occlusion?.right_eye > 0.6 || 
            quality.occlusion?.nose > 0.7 || 
            quality.occlusion?.mouth > 0.7) {
          setSearchResult({ found: false, error: '人脸被遮挡' });
          return;
        }
        
        if (quality.blur > 0.7) {
          setSearchResult({ found: false, error: '图片模糊' });
          return;
        }
        
        if (quality.illumination < 20) {
          setSearchResult({ found: false, error: '光线不足' });
          return;
        }
      }
      
      // 检查活体检测
      if (face.liveness && face.liveness.liveness < 0.8) {
        setSearchResult({ found: false, error: '活体检测失败' });
        return;
      }
      
      // 进行人脸搜索
      const searchResult = await searchFace(base64Image, {
        qualityControl,
        livenessControl,
        spoofingControl: 'NORMAL',
        maxUserNum: 1,
        matchThreshold: threshold
      });
      
      if (!searchResult.success) {
        setSearchResult({ found: false, error: searchResult.error, errorType: searchResult.errorType });
        return;
      }

      const userList = searchResult.data.user_list;
      
      if (!userList || userList.length === 0) {
        setSearchResult({ found: false, error: '未找到匹配的用户' });
        return;
      }

      const user = userList[0];
      const score = user.score;
      
      if (score < threshold) {
        setSearchResult({ found: false, score, error: `匹配度不足（${score}%）` });
        return;
      }

      // 识别成功，停止自动检测
      stopCamera();
      setSearchResult({ found: true, user, score });
      Toast.show(`识别成功！匹配度：${score}%`);
      
      // 延迟一下再调用成功回调
      setTimeout(() => {
        onSuccess?.(user);
        handleClose();
      }, 1000);
      
    } catch (error) {
      console.error('人脸识别失败:', error);
      setSearchResult({ found: false, error: '识别失败' });
    } finally {
      setIsProcessing(false);
    }
  }, [qualityControl, livenessControl, threshold, onSuccess, handleClose, isProcessing, stopCamera]);

  // 去注册
  const handleGoRegister = useCallback(() => {
    handleClose();
    onRegister?.();
  }, [handleClose, onRegister]);

  // 重新开始检测
  const handleRestart = useCallback(() => {
    setDetectResult(null);
    setSearchResult(null);
    if (!streamRef.current) {
      startCamera();
    }
  }, [startCamera]);

  // 组件挂载时启动摄像头
  useEffect(() => {
    if (visible) {
      startCamera();
    }
    
    return () => {
      stopCamera();
    };
  }, [visible, startCamera, stopCamera]);

  return (
    <Dialog
      visible={visible}
      onClose={handleClose}
      title="人脸登录"
      content={
        <div className={styles['face-login']}>
          {cameraError ? (
            <div className={styles['face-login-error']}>
              <div className={styles['face-login-error-icon']}>⚠️</div>
              <h3>摄像头启动失败</h3>
              <p>{cameraError}</p>
              <Button color="primary" onClick={startCamera}>
                重试
              </Button>
            </div>
          ) : (
            <div className={styles['face-login-camera']}>
              <div className={styles['face-login-video-container']}>
                <video
                  ref={videoRef}
                  className={styles['face-login-video']}
                  autoPlay
                  muted
                  playsInline
                />
                <canvas
                  ref={canvasRef}
                  className={styles['face-login-canvas']}
                  style={{ display: 'none' }}
                />
                
                {isDetecting && (
                  <div className={styles['face-login-detecting']}>
                    <div className={styles['face-login-detecting-icon']}>👁️</div>
                    <div className={styles['face-login-detecting-text']}>
                      正在检测人脸... ({detectionCount}次)
                    </div>
                  </div>
                )}
                
                {/* 人脸检测框提示 */}
                <div className={styles['face-login-face-guide']}>
                  <div className={styles['face-guide-frame']}>
                    <div className={styles['face-guide-text']}>请将人脸对准此框</div>
                  </div>
                </div>
                
                {isProcessing && (
                  <div className={styles['face-login-processing-overlay']}>
                    <div className={styles['face-login-spinner']} />
                    <div>正在识别中...</div>
                  </div>
                )}
              </div>
              
              {detectResult && (
                <div className="face-login-detect-info">
                  <h4>检测结果：</h4>
                  <p>年龄：{detectResult.age}岁</p>
                  <p>性别：{detectResult.gender?.type === 'male' ? '男' : '女'}</p>
                  <p>表情：{detectResult.expression?.type === 'smile' ? '微笑' : '自然'}</p>
                </div>
              )}
              
              {searchResult && (
                <div className={styles['face-login-search-result']}>
                  {searchResult.found ? (
                    <div className={styles['face-login-success']}>
                      <div className={styles['face-login-success-icon']}>✓</div>
                      <h3>识别成功！</h3>
                      <p>用户：{searchResult.user.user_info || searchResult.user.user_id}</p>
                      <p>匹配度：{searchResult.score}%</p>
                    </div>
                  ) : (
                    <div className={styles['face-login-failed']}>
                      <div className={styles['face-login-failed-icon']}>✗</div>
                      <h3>识别失败</h3>
                      <p>{searchResult.error || '未找到匹配的用户'}</p>
                      {searchResult.score && (
                        <p>匹配度：{searchResult.score}%</p>
                      )}
                      {searchResult.errorType && (
                        <div className={styles['face-login-error-tips']}>
                          {searchResult.errorType === 'quality' && (
                            <p className={styles['error-tip']}>💡 建议：确保光线充足，人脸清晰无遮挡</p>
                          )}
                          {searchResult.errorType === 'liveness' && (
                            <p className={styles['error-tip']}>💡 建议：请使用真人照片，避免使用照片翻拍</p>
                          )}
                          {searchResult.errorType === 'spoofing' && (
                            <p className={styles['error-tip']}>💡 建议：请使用真实照片，避免使用合成图片</p>
                          )}
                          {searchResult.errorType === 'rate_limit' && (
                            <p className={styles['error-tip']}>💡 建议：API调用频率过高，请等待5秒后重试</p>
                          )}
                        </div>
                      )}
                    </div>
                  )}
                </div>
              )}
              
              <div className={styles['face-login-tips']}>
                <h4>📋 使用说明：</h4>
                <ul>
                  <li>✅ 请将人脸对准蓝色检测框</li>
                  <li>✅ 确保光线充足，人脸清晰</li>
                  <li>✅ 保持稳定，避免模糊</li>
                  <li>✅ 系统每5秒自动检测一次</li>
                </ul>
                
                {lastDetectionTime && (
                  <div className={styles['face-login-status']}>
                    <p>🔍 检测次数: {detectionCount}</p>
                    <p>⏰ 上次检测: {lastDetectionTime.toLocaleTimeString()}</p>
                  </div>
                )}
              </div>
              
              <div className={styles['face-login-actions']}>
                <Button 
                  onClick={handleManualCapture} 
                  disabled={isProcessing}
                  color="primary"
                  size="large"
                >
                  {isProcessing ? '🔄 识别中...' : '📸 手动识别'}
                </Button>
                
                {searchResult && !searchResult.found && (
                  <Button color="success" onClick={handleGoRegister}>
                    📝 去注册
                  </Button>
                )}
                
                {searchResult && (
                  <Button onClick={handleRestart} fill="outline">
                    🔄 重新检测
                  </Button>
                )}
              </div>
            </div>
          )}
        </div>
      }
      actions={[
        {
          key: 'cancel',
          text: '取消',
          onClick: handleClose
        }
      ]}
    />
  );
};

export default FaceLogin;
